package com.empl.mgr.activiti.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class ApiDemo {
	
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
			new String[] { "classpath:spring-context.xml", "classpath:activiti.cfg.xml" });

	private ProcessEngine processEngine = (ProcessEngine) applicationContext.getBean("processEngine");
	
	
	/*部署流程定义 方式1*/
	public Deployment deploymentProcessDefinition_classpath(String bpmnPath, String pngPath){
		
		Deployment deployment = processEngine.getRepositoryService()
					 .createDeployment()
					 .name("Test activiti Demo")
					 .addClasspathResource(bpmnPath)
					 .addClasspathResource(pngPath)
					 .deploy();
		System.out.println("部署Id：" + deployment.getId());
		System.out.println("部署名字" + deployment.getName());
		return deployment;
	}
	
	
	/*部署流程定义  方式2*/
	public Deployment deploymentProcessDefinition_zip(){
		InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagraws/apiDemo/Demo.zip");
		ZipInputStream zipInputStream = new ZipInputStream(in);
		Deployment deployment = processEngine.getRepositoryService()
					 .createDeployment()
					 .name("Test activiti Demo")
					 .addZipInputStream(zipInputStream)
					 .deploy();
		System.out.println("部署Id：" + deployment.getId());
		System.out.println("部署名字" + deployment.getName());
		return deployment;
	}
	
	
	/*启动流程  方式1  此处的key 来自于Demo.bpmn xml中的 process id="DemoProcess"*/
	public ProcessInstance startProcessInstanceByKey(String key){
		ProcessInstance pi = processEngine.getRuntimeService()
		             .startProcessInstanceByKey(key);
		System.out.println("流程实例ID：" + pi.getId());
		System.out.println("流程定义ID：" + pi.getProcessDefinitionId());
		return pi;
	}
	
	/*启动流程  带参数*/
	public ProcessInstance startProcessInstanceByKey(String key, Map<String, Object> variables){
		ProcessInstance pi = processEngine.getRuntimeService()
		             .startProcessInstanceByKey(key, variables);
		System.out.println("流程实例ID：" + pi.getId());
		System.out.println("流程定义ID：" + pi.getProcessDefinitionId());
		return pi;
	}
	
	/*启动流程 方式2(建议使用方式一)其中deploymentId == Deployment id*/
	public ProcessInstance startProcessInstanceById(String deploymentId){
		ProcessDefinition pd = processEngine.getRepositoryService().createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
		ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceById(pd.getId());
		System.out.println("流程实例ID：" + pi.getId());
		System.out.println("流程定义ID：" + pi.getProcessDefinitionId());
		return pi;
	}

	
	/*查询流程定义*/
	public List<Deployment> findProcessDefinition(String deploymentId){
		List<Deployment> deploymentLists = processEngine.getRepositoryService()
				     .createDeploymentQuery()
				     .deploymentId(deploymentId)
				     .list();
				     //.listPage(0, 10);
		System.out.println("当前查询流程定义为：" + deploymentLists);
		return deploymentLists;
	}
	
	
	/*删除流程定义*/
	public void delProcessDefinition(String deploymentId){
		processEngine.getRepositoryService()
					 .deleteDeployment(deploymentId,true);//true 表示能级联删除流程
	}
	
	
	/*删除流程实例*/
	public void delProcessProcessInstance(String processInstanceId, String deleteReason){
		processEngine.getRuntimeService().deleteProcessInstance(processInstanceId, deleteReason);
	}
	
	/*查询所有任务*/
	public List<Task> findAllTask() {
		
				
		List<Task> taskList = processEngine.getTaskService()
					 .createTaskQuery()
					 .list();
		/*System.out.println("当前总的任务个数：" + taskList.size());
		System.out.println("--------------------------------------------------------------");
		for(Task task : taskList){
			System.out.println();
			System.out.println("任务的Id：" + task.getId());
			System.out.println("任务的名称：" + task.getName());
			System.out.println("任务的办理人：" + task.getAssignee());
			System.out.println("任务的创建时间：" + task.getCreateTime());
			System.out.println("流程实例id：" + task.getProcessInstanceId());
		}
		System.out.println("--------------------------------------------------------------");*/
		return taskList;
	}
	
	/*查询当前人的个人任务*/
	public List<Task> findMyTaskByAssignee(String assignee) {
		
		List<Task> taskList = processEngine.getTaskService()
					 .createTaskQuery()
					 .taskAssignee(assignee)
					 .list();
		System.out.println("当前（" + assignee + "）的任务个数：" + taskList.size());
		System.out.println("--------------------------------------------------------------");
		for(Task task : taskList){
			System.out.println();
			System.out.println("任务的Id：" + task.getId());
			System.out.println("任务的名称：" + task.getName());
			System.out.println("任务的办理人：" + task.getId());
			System.out.println("任务的创建时间：" + task.getCreateTime());
		}
		System.out.println("--------------------------------------------------------------");
		return taskList;
	}
	
	
	/*完成任务*/
	public void completeMyProcessTask(String taskId){
		processEngine.getTaskService().complete(taskId);
		System.out.println("当前被完成任务的Id：" + taskId);
	}
	
	
	/*设置任务处理人*/
	public void setTaskAssignee(String taskId, String assignee){
		processEngine.getTaskService().setAssignee(taskId, assignee);
		System.out.println("当前任务assignee被处理人被设置为：" + assignee);
	}
	
	/*查看流程图*/
	public void viewPic(String deploymentId){
		List<String> resourceNameList = processEngine.getRepositoryService()
		             .getDeploymentResourceNames(deploymentId);
		String resourceName = resourceNameList.get(0);
		if(resourceName.indexOf("png") < 0){
			resourceName = resourceNameList.get(1);
		}
		InputStream in = processEngine.getRepositoryService()
		             .getResourceAsStream(deploymentId, resourceName);
		
		File file = new File("D:/" + resourceName);
		OutputStream os;
		try {
			os = new FileOutputStream(file);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
			os.write(buffer, 0, bytesRead);
			}
			os.close();
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 
	}
	
	
	/*查询最新版本的流程定义*/
	public List<ProcessDefinition> findLastVersionProcessDefinition(){
		List<ProcessDefinition> list = processEngine.getRepositoryService()
					 .createProcessDefinitionQuery()
					 .orderByProcessDefinitionVersion()
					 .asc()
					 .list();
		System.out.println("所有版本排序：" + list);
		return list;
	}
	
	/*设置流程变量*/
	public void setVariables(String taskId, Map<String, ?> varMap){
		TaskService taskService = processEngine.getTaskService();
		for(Entry<String, ?> entry : varMap.entrySet()){
			taskService.setVariable(taskId, entry.getKey(), entry.getValue());
		}
		
		System.out.println("流程变量设置成功！！！");
	}
	
	
	/*获取流程变量*/
	public void getVariables(String taskId,String key){
		TaskService taskService = processEngine.getTaskService();
		Object val = taskService.getVariable(taskId, key);
		System.out.println("变量" + key + "值为：" + val);
	}


	public ProcessEngine getProcessEngine() {
		return processEngine;
	}
	
	
	
	// 历史流程实例查看（查找按照某个规则一共执行了多少次流程）
	public void queryHistoricProcessInstance(String activitiInstId){
		// 获取历史流程实例的查询对象
		HistoricProcessInstanceQuery historicProcessInstanceQuery = processEngine.getHistoryService().createHistoricProcessInstanceQuery();
		// 设置查询参数
		historicProcessInstanceQuery
		
				// 过滤条件
				.processInstanceId(activitiInstId)
				//.processDefinitionKey(activitiInstId)
				// 分页条件
				// .listPage(firstResult, maxResults)
				// 排序条件
				.orderByProcessInstanceStartTime().desc();
		// 执行查询
		List<HistoricProcessInstance> hpis = historicProcessInstanceQuery.list();
		// 遍历查看结果
		for (HistoricProcessInstance hpi : hpis) {
			System.out.print("pid:" + hpi.getId() + ",");
			System.out.print("pdid:" + hpi.getProcessDefinitionId() + ",");
			System.out.print("startTime:" + hpi.getStartTime() + ",");
			System.out.print("endTime:" + hpi.getEndTime() + ",");
			System.out.print("duration:" + hpi.getDurationInMillis() + ",");
			System.out.println("vars:" + hpi.getProcessVariables());
		}

	}
	
}
